home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 30
/
Aminet 30 (1999)(Schatztruhe)[!][Apr 1999].iso
/
Aminet
/
dev
/
lang
/
SmallEiffel.lha
/
SmallEiffel
/
lib_show
/
pyramid.e
< prev
next >
Wrap
Text File
|
1998-12-22
|
6KB
|
244 lines
-- This file is part of SmallEiffel The GNU Eiffel Compiler.
-- Copyright (C) 1994-98 LORIA - UHP - CRIN - INRIA - FRANCE
-- Dominique COLNET and Suzanne COLLIN - colnet@loria.fr
-- http://www.loria.fr/SmallEiffel
-- SmallEiffel is free software; you can redistribute it and/or modify it
-- under the terms of the GNU General Public License as published by the Free
-- Software Foundation; either version 2, or (at your option) any later
-- version. SmallEiffel is distributed in the hope that it will be useful,but
-- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-- for more details. You should have received a copy of the GNU General
-- Public License along with SmallEiffel; see the file COPYING. If not,
-- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-- Boston, MA 02111-1307, USA.
--
class PYRAMID
--
-- Solving the problem of the Pyramid for small pyramid only.
--
--| This program uses the back-tracking method.
--| Its goal is to try to fill a pyramid by making a substraction
--| between two succesive columns and to take its absolute value.
--| The result is put on the next line.
--| Example :
--| 6 14 15 3 13
--| 8 1 12 10
--| 7 11 2
--| 4 9
--| 5
--
-- See also pyramid2, which run faster than this first solution.
inherit
ANY
redefine
out_in_tagged_out_memory
end;
creation make
feature
size : INTEGER;
make is
do
if argument_count = 0 then
std_output.put_string("Want to compute a small pyramid ?%N%
%Enter a small number (> 1) : ");
std_output.flush;
std_input.read_integer;
size := std_input.last_integer;
else
size := argument(1).to_integer;
end;
if size <= 1 then
std_output.put_string("You feel sick ?%N");
elseif size > biggest_one then
std_output.put_string("Value too big for this method.%N");
else
!!elem.make(1,max);
if fill_up(1) then
std_output.put_string("Full pyramid :%N");
print_on(std_output);
else
std_output.put_string("Unable to fill_up such one.%N");
end;
end;
end; -- make
max : INTEGER is
do
Result := (size * (size + 1)) // 2;
end; -- max
out_in_tagged_out_memory is
local
lig,col,nb : INTEGER;
do
from
lig := 1;
col := 1;
nb := 0;
until
nb = max
loop
if col = 1 then
tagged_out_memory.extend('%N');
end;
(elem.item(indice(lig,col))).append_in(tagged_out_memory);
tagged_out_memory.append(" ");
if col = size - lig + 1 then
col := 1 ;
lig := lig + 1 ;
else
col := col + 1;
end;
nb := nb + 1;
end;
tagged_out_memory.extend('%N');
end;
belongs_to(nb : INTEGER): BOOLEAN is
require
nb_trop_petit: nb >= 1;
nb_trop_grand: nb <= max;
local
i : INTEGER;
trouve : BOOLEAN;
do
from
i := 1;
trouve := false;
until
((i > max) or trouve)
loop
trouve := (nb = elem.item(i));
i := i + 1;
end;
Result := trouve;
end; -- belongs_to
propagate (col, val_column_1: INTEGER): BOOLEAN is
require
val_column_1 >= 1;
val_column_1 <= max;
col >= 1;
col <= size;
local
stop : BOOLEAN;
lig : INTEGER;
val : INTEGER;
do
if belongs_to(val_column_1) then
Result := false ;
else
from
elem.put(val_column_1,indice(1,col));
lig := 1;
val := val_column_1;
stop := false;
Result := true;
until
stop
loop
lig := lig + 1;
if lig > col then
stop := true;
else
val := val - elem.item(indice(lig-1,col-lig+1));
if val < 0 then -- valeur absolue !
val := - val ;
end;
if belongs_to(val) then
clear_column(col);
stop := true;
Result := false;
else
elem.put(val,indice(lig,col-lig+1));
end;
end;
end;
end;
end; -- propagate
fill_up (col : INTEGER) : BOOLEAN is
require
col >= 1;
local
stop : BOOLEAN;
nb : INTEGER;
do
if col > size then
Result := true;
else
from
stop := false;
nb := max;
until
stop
loop
if belongs_to(nb) then
nb := nb - 1;
stop := (nb = 0);
elseif propagate(col,nb) then
if fill_up(col + 1) then
stop := true;
else
clear_column(col);
nb := nb - 1;
stop := (nb = 0);
end;
else
nb := nb - 1;
stop := (nb = 0);
end;
end;
Result := (nb > 0);
end;
end; -- fill_up
feature {NONE}
elem: ARRAY[INTEGER];
case_vide : INTEGER is 0;
biggest_one: INTEGER is 10;
indice (lig,col : INTEGER): INTEGER is
require
lig_trop_petit: lig >= 1 ;
lig_trop_grand: lig <= size ;
col_trop_petit: col >= 1 ;
col_trop_grand: col <= size ;
local
l : INTEGER ;
do
l:= size - lig + 1;
Result := max - ((l * (l + 1)) // 2) + col;
ensure
Result >= 1 ;
Result <= max ;
end; -- indice
clear_column (col : INTEGER) is
require
col >= 1;
col <= size;
local
lig : INTEGER;
do
from
lig := 1;
until
lig > col
loop
elem.put(case_vide,indice(lig,col-lig+1));
lig := lig + 1;
end;
end; -- clear_column
end -- PYRAMID